package com.dy.lock.screen.component.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.dy.lock.screen.component.GoodsInfoComponent;
import com.dy.lock.screen.constants.Constant;
import com.dy.lock.screen.constants.TransmissionCode;
import com.dy.lock.screen.exception.ServerDisponseException;
import com.dy.lock.screen.pojo.GoodsInfo;
import com.dy.lock.screen.pojo.Location;
import com.dy.lock.screen.pojo.MerchantAddress;
import com.dy.lock.screen.scoket.Head;
import com.dy.lock.screen.service.GoodsService;
import com.dy.lock.screen.service.MerchantAddressService;
import com.dy.lock.screen.utils.CommonUtil;
import com.dy.lock.screen.utils.LocationUtil;
import com.dy.lock.screen.vo.GoodsResultVo;
import com.dy.lock.screen.vo.GoodsVo;
import com.google.gson.Gson;

@Component("goodsInfoComponent")
public class GoodsInfoComponentImpl implements GoodsInfoComponent {
	private static final Logger log = Logger
			.getLogger(GoodsInfoComponentImpl.class);
	private Gson gson;

	@Resource(name = "goodsService")
	private GoodsService goodsService;
	@Resource(name = "merchantAddressService")
	private MerchantAddressService merchantAddressService;

	public GoodsInfoComponentImpl() {
		gson = CommonUtil.gson();
	}

	@Override
	public List<GoodsResultVo> list(String body, Head head) {
		GoodsVo vo = gson.fromJson(body, GoodsVo.class);
		if (vo != null) {
			Integer currentPage = vo.getPageIndex();
			Integer pageSize = vo.getPageCount();
			Integer pageStart = 1;
			Integer pageEnd = 10;
			if (currentPage != null && pageSize != null) {
				pageStart = (currentPage - 1) * pageSize + 1;
				pageEnd = currentPage * pageSize;
			}
			Map<String, Object> paraMap = new HashMap<String, Object>();
			paraMap.put("pageStart", pageStart);
			paraMap.put("pageEnd", pageEnd);
			paraMap.put("isDelete", "1");
			paraMap.put("goodsState", "1");
			if ("0".equals(vo.getGoodsCategory())) {
				paraMap.put("goodsCategory", "");
			} else {
				paraMap.put("goodsCategory", vo.getGoodsCategory());
			}

			if (Constant.ORDER_TYPE_ASC.equals(vo.getOrderType())) {
				if ("sell_out".equals(vo.getOrderBy())) {
					paraMap.put("page_orderByAsc",
							" (nvl(gd.goods_num,0)-nvl(gd.goods_stock,0))");
				} else
					paraMap.put("page_orderByAsc", "gd." + vo.getOrderBy());
			} else {
				if ("sell_out".equals(vo.getOrderBy())) {
					paraMap.put("page_orderByDesc",
							" (nvl(gd.goods_num,0)-nvl(gd.goods_stock,0))");
				} else
					paraMap.put("page_orderByDesc", "gd." + vo.getOrderBy());
			}
			List<GoodsInfo> goodsInfoList = this.goodsService.queryPage(
					paraMap, head);
			List<GoodsResultVo> goodsVoList = new ArrayList<GoodsResultVo>();
			if (goodsInfoList != null && !goodsInfoList.isEmpty()) {
				for (GoodsInfo info : goodsInfoList) {
					GoodsResultVo goodsResVo = new GoodsResultVo();
					goodsResVo.setGoodsId(info.getGoodsId());
					goodsResVo.setGoodsName(info.getGoodsName());
					if (info.getGoodsPhotoPath() != null) {
						String photoUrl = info.getGoodsPhotoPath().split(";")[0];
						goodsResVo.setGoodsPhotoURL(CommonUtil.getUrlPrefix()
								+ photoUrl);
					}
					goodsResVo.setStockTotal(info.getGoodsNum());
					goodsResVo.setStockSurplus(info.getGoodsStock());
					goodsResVo.setGoodsPrice(info.getGoodsPrice());
					goodsResVo.setExchangeway(info.getExchangeType());
					String merchantId = info.getMerchantId();
					List<MerchantAddress> addressList = this.merchantAddressService
							.queryByMerchantId(merchantId, head);
					try {
						double minDistance = getMinDistance(addressList, vo);
						goodsResVo.setDistance(minDistance);
					} catch (Exception e) {
						log.error("requestId:" + head.getRequestId()
								+ "，计算最小距离时出现异常", e);
						throw new ServerDisponseException(
								TransmissionCode.CAL_MIN_DISTANCE_ERROR
										.getCode(),
								TransmissionCode.CAL_MIN_DISTANCE_ERROR
										.getMessage());
					}
					goodsVoList.add(goodsResVo);
				}
				return goodsVoList;

			} else {
				return new ArrayList<GoodsResultVo>();
			}

		} else {
			log.info("requestId:" + head.getRequestId() + ",获取商品列表时，报文解析异常。");
			throw new ServerDisponseException(TransmissionCode.ERROR_ADJUST
					.getCode(), TransmissionCode.ERROR_ADJUST.getMessage());
		}
	}

	@Override
	public List<GoodsResultVo> locationList(String body, Head head) {
		GoodsVo vo = gson.fromJson(body, GoodsVo.class);
		if (vo != null) {
			Integer currentPage = vo.getPageIndex();
			Integer pageSize = vo.getPageCount();
			Integer pageStart = 1;
			Integer pageEnd = 10;
			if (currentPage != null && pageSize != null) {
				pageStart = (currentPage - 1) * pageSize + 1;
				pageEnd = currentPage * pageSize;
			}
			Map<String, Object> paraMap = new HashMap<String, Object>();
			paraMap.put("pageStart", pageStart);
			paraMap.put("pageEnd", pageEnd);
			paraMap.put("isDelete", "1");
			paraMap.put("goodsState", "1");
			List<GoodsInfo> goodsInfoList = this.goodsService.queryPage(
					paraMap, head);
			List<GoodsResultVo> goodsVoList = new ArrayList<GoodsResultVo>();
			if (goodsInfoList != null && !goodsInfoList.isEmpty()) {
				for (GoodsInfo info : goodsInfoList) {
					GoodsResultVo goodsResVo = new GoodsResultVo();
					goodsResVo.setGoodsName(info.getGoodsName());
					if (info.getGoodsPhotoPath() != null) {
						String photoUrl = info.getGoodsPhotoPath().split(";")[0];
						goodsResVo.setGoodsPhotoURL(CommonUtil.getUrlPrefix()
								+ photoUrl);
					}
					goodsResVo.setStockTotal(info.getGoodsNum());
					goodsResVo.setStockSurplus(info.getGoodsStock());
					goodsResVo.setGoodsPrice(info.getGoodsPrice());
					goodsResVo.setExchangeway(info.getExchangeType());
					String merchantId = info.getMerchantId();
					List<MerchantAddress> addressList = this.merchantAddressService
							.queryByMerchantId(merchantId, head);
					List<Location> locations = getLocations(addressList);
					goodsResVo.setLocations(locations);
					goodsVoList.add(goodsResVo);
				}
				return goodsVoList;

			} else {
				return new ArrayList<GoodsResultVo>();
			}

		} else {
			log.info("requestId:" + head.getRequestId() + ",获取商品列表时，报文解析异常。");
			throw new ServerDisponseException(TransmissionCode.ERROR_ADJUST
					.getCode(), TransmissionCode.ERROR_ADJUST.getMessage());
		}
	}

	private static List<Location> getLocations(List<MerchantAddress> addressList) {
		List<Location> list = new ArrayList<Location>();
		if (addressList != null && !addressList.isEmpty()) {
			for (MerchantAddress madd : addressList) {
				Location loc = new Location();
				loc.setLat(madd.getLat());
				loc.setLng(madd.getLng());
				list.add(loc);
			}
		}
		return list;
	}

	/**
	 * 获取最小距离
	 * 
	 * @param addressList
	 * @param vo
	 * @return
	 */
	private static double getMinDistance(List<MerchantAddress> addressList,
			GoodsVo vo) {
		double minDistance = 0;
		List<Double> distances = getDistanceList(addressList, vo);
		if (distances != null && !distances.isEmpty()) {
			minDistance = Collections.min(distances);
		} else {
			minDistance = 0;
		}
		return minDistance;
	}

	/**
	 * 获取距离列表
	 * 
	 * @param addressList
	 * @param vo
	 * @return
	 */
	private static List<Double> getDistanceList(
			List<MerchantAddress> addressList, GoodsVo vo) {
		Float sourceLat = vo.getLat();
		Float sourceLng = vo.getLng();
		List<Double> disList = new ArrayList<Double>();
		if (addressList != null && !addressList.isEmpty()) {
			for (MerchantAddress add : addressList) {
				if (add != null) {
					Float targetLat = add.getLat();
					Float targetLng = add.getLng();
					if (targetLat != null && targetLng != null) {
						Double dis = LocationUtil.calDistance(sourceLat,
								sourceLng, targetLat, targetLng);
						disList.add(dis);
					}
				}
			}
		}
		return disList;
	}

	@Override
	public GoodsResultVo getGoodsDetail(String body, Head head) {
		GoodsVo vo = gson.fromJson(body, GoodsVo.class);
		if (vo != null && StringUtils.isNotBlank(vo.getGoodsId())) {
			GoodsInfo info = this.goodsService.queryByPrimaryKey(vo
					.getGoodsId());
			GoodsResultVo goodsResVo = new GoodsResultVo();
			goodsResVo.setGoodsName(info.getGoodsName());
			if (info.getGoodsPhotoPath() != null) {
				String[] photoUrl = info.getGoodsPhotoPath().split(";");
				StringBuilder sb = new StringBuilder();
				if (photoUrl != null) {
					for (String url : photoUrl) {
						sb.append(CommonUtil.getUrlPrefix() + url);
						sb.append(";");
					}
				}
				String path = sb.toString();
				goodsResVo.setGoodsPhotoURL(path
						.substring(0, path.length() - 1));
			}
			goodsResVo.setStockTotal(info.getGoodsNum());
			goodsResVo.setStockSurplus(info.getGoodsStock());
			goodsResVo.setGoodsPrice(info.getGoodsPrice());
			goodsResVo.setExchangeway(info.getExchangeType());
			goodsResVo.setReleaseTme(info.getPublishTime());
			goodsResVo.setDescription(info.getGoodsDesc());
			goodsResVo.setUseRule(info.getUseRule());
			return goodsResVo;
		} else {
			log.info("requestId:" + head.getRequestId() + ",获取商品详情时，报文解析异常。");
			throw new ServerDisponseException(TransmissionCode.ERROR_ADJUST
					.getCode(), TransmissionCode.ERROR_ADJUST.getMessage());
		}
	}
}
